/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* Copyright 2012 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

/* globals PDFFindController, FindStates, mozL10n */

/**
 * Creates a "search bar" given set of DOM elements
 * that act as controls for searching, or for setting
 * search preferences in the UI. This object also sets
 * up the appropriate events for the controls. Actual
 * searching is done by PDFFindController
 */
var PDFFindBar = {

    opened: false,
    bar: null,
    toggleButton: null,
    findField: null,
    highlightAll: null,
    caseSensitive: null,
    findMsg: null,
    findStatusIcon: null,
    findPreviousButton: null,
    findNextButton: null,

    initialize: function (options) {
        if (typeof PDFFindController === 'undefined' || PDFFindController === null) {
            throw 'PDFFindBar cannot be initialized ' +
                'without a PDFFindController instance.';
        }

        this.bar = options.bar;
        this.toggleButton = options.toggleButton;
        this.findField = options.findField;
        this.highlightAll = options.highlightAllCheckbox;
        this.caseSensitive = options.caseSensitiveCheckbox;
        this.findMsg = options.findMsg;
        this.findStatusIcon = options.findStatusIcon;
        this.findPreviousButton = options.findPreviousButton;
        this.findNextButton = options.findNextButton;

        var self = this;
        this.toggleButton.addEventListener('click', function () {
            self.toggle();
        });

        this.findField.addEventListener('input', function () {
            self.dispatchEvent('');
        });

        this.bar.addEventListener('keydown', function (evt) {
            switch (evt.keyCode) {
                case 13: // Enter
                    if (evt.target === self.findField) {
                        self.dispatchEvent('again', evt.shiftKey);
                    }
                    break;
                case 27: // Escape
                    self.close();
                    break;
            }
        });

        this.findPreviousButton.addEventListener('click',
            function () {
                self.dispatchEvent('again', true);
            }
        );

        this.findNextButton.addEventListener('click', function () {
            self.dispatchEvent('again', false);
        });

        this.highlightAll.addEventListener('click', function () {
            self.dispatchEvent('highlightallchange');
        });

        this.caseSensitive.addEventListener('click', function () {
            self.dispatchEvent('casesensitivitychange');
        });
    },

    dispatchEvent: function (aType, aFindPrevious) {
        var event = document.createEvent('CustomEvent');
        event.initCustomEvent('find' + aType, true, true, {
            query: this.findField.value,
            caseSensitive: this.caseSensitive.checked,
            highlightAll: this.highlightAll.checked,
            findPrevious: aFindPrevious
        });
        return window.dispatchEvent(event);
    },

    updateUIState: function (state, previous) {
        var notFound = false;
        var findMsg = '';
        var status = '';

        switch (state) {
            case FindStates.FIND_FOUND:
                break;

            case FindStates.FIND_PENDING:
                status = 'pending';
                break;

            case FindStates.FIND_NOTFOUND:
                findMsg = mozL10n.get('find_not_found', null, 'Phrase not found');
                notFound = true;
                break;

            case FindStates.FIND_WRAPPED:
                if (previous) {
                    findMsg = mozL10n.get('find_reached_top', null,
                        'Reached top of document, continued from bottom');
                } else {
                    findMsg = mozL10n.get('find_reached_bottom', null,
                        'Reached end of document, continued from top');
                }
                break;
        }

        if (notFound) {
            this.findField.classList.add('notFound');
        } else {
            this.findField.classList.remove('notFound');
        }

        this.findField.setAttribute('data-status', status);
        this.findMsg.textContent = findMsg;
    },

    open: function () {
        if (!this.opened) {
            this.opened = true;
            this.toggleButton.classList.add('toggled');
            this.bar.classList.remove('hidden');
        }

        this.findField.select();
        this.findField.focus();
    },

    close: function () {
        if (!this.opened) return;

        this.opened = false;
        this.toggleButton.classList.remove('toggled');
        this.bar.classList.add('hidden');

        PDFFindController.active = false;
    },

    toggle: function () {
        if (this.opened) {
            this.close();
        } else {
            this.open();
        }
    }
};

